package com.example.demo.config;

import com.example.demo.interceptor.CorsIntercepteor;
import com.example.demo.xss.XssFilter;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * Author:shialang
 * 2020/7/27
 */
@Configuration
public class SpringConfig extends WebMvcConfigurationSupport {
	@Value("${spring.profiles.active}")
	private String active;
	// 不需要过 校验 认证 的接口或静态资源
	private static String[] exc = new String[]{
			"/swagger-resources/**",
			"/webjars/**",
			"/swagger-ui.html**",
			"/doc.html**",
			"/csrf",
			"/error",
			"/dev/**",
			"/",
			"/common/file/getImg",
			"/common/file/download",
			// 忽略共享接口
			"/share/**"
	};
	@Autowired
	private CorsIntercepteor corsIntercepteor;

	//注册拦截器
	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		registry.addInterceptor(corsIntercepteor)
				.addPathPatterns("/**");
//		registry.addInterceptor(verifyInterceptor)
//				.addPathPatterns("/**")
//				.excludePathPatterns(exc);
//		registry.addInterceptor(authInterceptor)
//				.addPathPatterns("/**")
//				.excludePathPatterns(exc);
		super.addInterceptors(registry);
	}

	/**
	 * 跨域支持
	 *
	 * @param registry
	 */
	@Override
	public void addCorsMappings(CorsRegistry registry) {
		registry.addMapping("/**")
				.allowedOrigins("*")
				.allowCredentials(true)
				.allowedMethods("GET", "POST", "DELETE", "PUT")
				.maxAge(3600 * 24);
	}


	/**
	 * XssFilter Bean
	 */
	@Bean
	public FilterRegistrationBean<XssFilter> xssFilterRegistrationBean() {
		FilterRegistrationBean<XssFilter> filterRegistrationBean = new FilterRegistrationBean<>();
		filterRegistrationBean.setFilter(new XssFilter());
		filterRegistrationBean.setOrder(1);
		filterRegistrationBean.setEnabled(true);
		filterRegistrationBean.addUrlPatterns("/*");
		Map<String, String> initParameters = new HashMap<>(2);
		initParameters.put("excludes", "/favicon.ico,/img/*,/js/*,/css/*");
		initParameters.put("isIncludeRichText", "true");
		filterRegistrationBean.setInitParameters(initParameters);
		return filterRegistrationBean;
	}

	// 为了解决long精度丢失的问题
	// @see
	// [修复Long类型太长，而Java序列化JSON丢失精度问题的方法]
	// (https://www.jianshu.com/p/fbcdcfc7cd12)
	@Override
	public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
		MappingJackson2HttpMessageConverter jackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();

		ObjectMapper objectMapper = new ObjectMapper();
		/**
		 * 序列换成json时,将所有的long变成string
		 * 因为js中得数字类型不能包含所有的java long值
		 */
		SimpleModule simpleModule = new SimpleModule();
		simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
		simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
		objectMapper.registerModule(simpleModule);

		jackson2HttpMessageConverter.setObjectMapper(objectMapper);
		converters.add(jackson2HttpMessageConverter);
	}
}
